let ErrorUtils = require('../utils/error/ErrorUtils');
let {User, BaseUserInfo, LearningExperience, UserUploadPic, UserApply, Order,Liuyan} = require('../models');
let lodash = require('lodash');
const {infoLogger, errorLogger} = require('../config').logger;
const Joi = require('joi');
const config = require('../config');
const redis = require('../redis');
const crypto = require('crypto');
const md5 = crypto.createHash('md5');
let EmailService = require('../service/email');

class AdminUserService {
    static async index(content) {
        return content;
    }

    /**
     * 核验基本信息
     * @param data
     * @returns {*}
     */
    static checkBaseValiData(data) {
        let schema = Joi.object({
            name: Joi.string().min(2).max(20).required(),//姓名
            sex: Joi.number().required(),//性别
            nationality: Joi.object().keys({
                code: Joi.string().required(),
                en: Joi.string().required(),
                cn: Joi.string().required(),
            }).required(),//国籍
            deliveryDistrict: Joi.object().required(),//区
            deliveryCity: Joi.object().required(),//市
            deliveryProvince: Joi.object().required(),//省
            deliveryAddress: Joi.string().max(40).required(),//详情地址
            receiver: Joi.string().min(2).max(20).required(),//收件人
            receiverTel: Joi.string().min(11).max(11).required(),//收件人手机号
        });
        return Joi.validate(data, schema);
    }

    /**
     *  保存用户基本信息
     * @param ctx
     * @returns {Promise<void>}
     */
    static async saveBaseUserInfo(ctx) {
        let data = ctx.request.body;
        infoLogger.info('>>>>>>基本信息保存开始,请求参数为:', data);
        //await AdminUserService.checkBaseValiData(data);
        let baseUser = await BaseUserInfo.findOne({userId: ctx.currentUser._id}).lean().exec();
        infoLogger.info('>>>>>>基本信息保存开始,请求参数为:', baseUser);
        data = lodash.pick(data, [
            'birthday', 'sex', 'nationality', 'deliveryDistrict', 'deliveryCity',
            'deliveryProvince', 'deliveryAddress', 'receiver', 'receiverTel',
        ]);
        if (data.sex) {
            data.sex = parseInt(data.sex);
            switch (data.sex) {
                case 0:
                    break;
                case 1:
                    break;
                default:
                    data.sex = 2;
                    break;
            }
        }
        data.userId = ctx.currentUser._id;
        if (baseUser) {
            await BaseUserInfo.update({_id: baseUser._id}, data);
        } else {
            await BaseUserInfo.create(data);
        }
        infoLogger.info(">>>>>>基本信息保存结束");
        return true;
    }

    /**
     *  保存用户基本信息
     * @param ctx
     * @returns {Promise<void>}
     */
    static async findBaseUserInfo(ctx) {
        infoLogger.info('>>>>>>基本信息查询开始');
        let data = {};
        let object = {
            sex: 0,
            birthday: '',
            nationality: {
                code: "",
                en: "",
                cn: ""
            },//国籍
            deliveryCity: {
                CityID: "",
                CityName: "",
                ProID: "",
                CitySort: ""
            },//市
            deliveryDistrict: {
                Id: "",
                DisName: "",
                CityID: "",
                DisSor: null
            },//区
            deliveryProvince: {
                ProID: "",
                ProName: "",
                ProSort: "",
                ProRemar: ""
            },//省
            deliveryAddress: '',//详情地址
            receiver: '',//收件人
            receiverTel: '',//收件人手机号
            authType: '',
        };
        let result = await BaseUserInfo.findOne({userId: ctx.currentUser._id})
            .lean()
            .exec();
        data.baseInfo = Object.assign(object, result);
        data.userInfo = ctx.currentUser;
        infoLogger.info(">>>>>>基本信息查询结束");
        return data;
    }

    /**
     * 核验认证类型
     * @param data
     * @returns {*}
     */
    static checkAuthTypeValiData(data) {
        let schema = Joi.object({
            authType: Joi.number().required(),//姓名
        });
        let result = Joi.validate(data, schema);
        return result;
    }

    /**
     * 核验学习经历
     * @param data
     * @returns {*}
     */
    static checkLearningExperienData(data) {
        let schema = Joi.object({
            studyCountry: Joi.string().min(2).max(30).required(),//就读国家
            schoolCnName: Joi.string().min(2).max(30).required(),//学校中文名
            schoolUsName: Joi.string().min(2).max(40).required(),//学校英文名
            schoolNature: Joi.string().min(3).max(30).required(),//学校性质
            degreeType: Joi.number().required(),//学位类型
            startTime: Joi.string().required(),//开始日期
            endTime: Joi.string().required(),//毕业日期
            majorCnName: Joi.string().min(2).max(20).required(),//专业中文名称
            majorUsName: Joi.string().min(2).max(20).required(),//专业英文名称
            majorType: Joi.string().min(2).max(30).required(),//专业类别 例如计算机
            certificateUsername: Joi.string().min(2).max(20).required(),//证书用户姓名
            studentId: Joi.string().required(),//学生id
            studentPwd: Joi.string().required(),//学生id密码
            ssn: Joi.string().required(),//ssn
            schoolWebsite: Joi.string().required(),//学校网址
            node: Joi.string().required(),//备注
        });
        let result = Joi.validate(data, schema);
        return result;
    }

    /**
     * 保存认证类型
     * @param ctx
     * @returns {Promise<void>}
     */
    static async saveAuthType(ctx) {
        let data = ctx.request.body;
        infoLogger.info('>>>>>>申请类型保存开始,请求参数', data);
        //await AdminUserService.checkAuthTypeValiData(data);
        let result = await BaseUserInfo.findOne({userId: ctx.currentUser._id}).exec();
        if (!result) {
            ErrorUtils.throwApiError(ErrorUtils.USER_BASE_NOT_EXISTS);
        }
        data.authType = parseInt(data.authType);
        switch (data.authType) {
            case 0:
                break;
            case 1:
                break;
            case 2:
                break;
            case 3:
                break;
            default:
                data.authType = 0;
                break;
        }
        result.authType = data.authType;
        return await result.save();
    }

    /**
     * 保存学习资料
     * @param ctx
     * @returns {Promise<boolean>}
     */
    static async saveLearningExperience(ctx) {
        let data = ctx.request.body;
        infoLogger.info('>>>>>>学习经历保存开始,请求参数', data);
        //await AdminUserService.checkLearningExperienData(data);
        let result = await LearningExperience.findOne({userId: ctx.currentUser._id});
        if (data.degreeType) {
            data.degreeType = parseInt(data.degreeType);
            switch (data.degreeType) {
                case 1:
                    break;
                case 2:
                    break;
                case 3:
                    break;
                default:
                    data.degreeType = 1;
                    break;
            }
        }
        infoLogger.info(">>>>>>基本信息查询结束");
        if (result) {
            await LearningExperience.update({_id: result._id}, data);
        } else {
            data.userId = ctx.currentUser._id;
            await LearningExperience.create(data);
        }
        return true;
    }

    /**
     * 查询学习资料
     * @param ctx
     * @returns {Promise<*>}
     */
    static async findLearningUserInfo(ctx) {
        infoLogger.info('>>>>>>学习经历查询开始,请求参数');
        let object = {
            schoolCnName: '',//学校中文名
            schoolUsName: '',//学校英文名
            studyCountry: '',//就读国家
            schoolNature: '',//学校性质
            degreeType: '',
            startTime: '',//开始日期
            endTime: '',//毕业时间
            majorCnName: '',//专业中文名称
            majorUsName: '',//专业英文名称
            majorType: '',//专业类别 例如计算机
            certificateUsername: '',//证书用户姓名
            studentId: '',//学生id
            studentPwd: '',//学生id密码
            ssn: '',//证书用户姓名
            schoolWebsite: '',//学校网址
            node: '',//备注
        };
        let result = await LearningExperience.findOne({userId: ctx.currentUser._id}).lean().exec();
        return Object.assign(object, result);
    }

    /**
     * 核验上传图片
     * @param data
     * @returns {*}
     */
    static checkUploadPicData(data) {
        let schema = Joi.object({
            frontalLogo: Joi.object().keys({
                logo: Joi.string().required(),
                node: Joi.string(),
            }).required(),//国籍
            idCard: Joi.object().keys({
                frontLogo: Joi.string().required(),//反面
                reverseLogo: Joi.string().required(),//正面
                node: Joi.string(),
            }),//身份证
            handheldFile: Joi.object().keys({
                logo: Joi.string().required(),
                node: Joi.string(),
            }).required(),//手持文件呢
            graduationCertificate: Joi.object().keys({
                logo: Joi.string().required(),
                node: Joi.string(),
            }).required(),//毕业证书
            reportCard: Joi.object().keys({
                logo: Joi.string().required(),
                node: Joi.string(),
            }).required(),//成绩单
            passport: Joi.object().keys({
                logo: Joi.string().required(),
                node: Joi.string(),
            }).required(),//护照
        });
        let result = Joi.validate(data, schema);
        return result;
    }

    /**
     * 保存上传图片
     * @param ctx
     * @returns {Promise<boolean>}
     */
    static async saveUploadPic(ctx) {
        let data = ctx.request.body;
        infoLogger.info('>>>>>>上传资料保存开始,请求参数', data);
        //await AdminUserService.checkUploadPicData(data);
        let result = await UserUploadPic.findOne({userId: ctx.currentUser._id});
        infoLogger.info(">>>>>>上传资料查询结束");
        if (result) {
            await UserUploadPic.update({_id: result._id}, data);
        } else {
            data.userId = ctx.currentUser._id;
            await UserUploadPic.create(data);
        }

        return true;
    }

    /**
     * 查询上传资料
     * @param ctx
     * @returns {Promise<*>}
     */
    static async findUploadPic(ctx) {
        infoLogger.info('>>>>>>上传资料查询开始,请求参数');
        let object = {
            frontalLogo: {
                logo: '',
                node: '',
            },//正面照
            idCard: {
                frontLogo: '',//反面
                reverseLogo: '',//正面
                node: '',
            },//身份证
            handheldFile: {
                logo: '',
                node: '',
            },//手持文件呢
            graduationCertificate: {
                logo: '',
                node: '',
            },//毕业证书
            reportCard: {
                logo: '',
                node: '',
            },//成绩单
            passport: {
                logo: '',
                node: '',
            },//护照
        };
        let result = await UserUploadPic.findOne({userId: ctx.currentUser._id}).lean().exec();

        return Object.assign(object, result)
    }

    static checkUpdatePasswordValiData(data) {
        let schema = Joi.object({
            oldPassword: Joi.string().min(6).max(16).required(),
            newPassword: Joi.string().min(6).max(16).required(),
            rePassword: Joi.string().min(6).max(16).required()
        });
        let result = Joi.validate(data, schema);
        return result;
    }

    /**
     *  修改密码
     * @param data
     * @returns {Promise<void>}
     */
    static async updatePassword(ctx) {
        let data = ctx.request.body;
        infoLogger.info('>>>>>>登录开始,请求参数为:', data);
        await AdminUserService.checkUpdatePasswordValiData(data);
        if (data.rePassword != data.newPassword) {
            ErrorUtils.throwApiError(ErrorUtils.TWICE_PASSWORD_NOT_SAME);
        }
        //老密码
        let password = data.oldPassword;
        password = password + config.auth.salt;
        password.toLowerCase();
       
        md5.update(password);
        password = md5.digest('hex');
        let userInfo = await User.findById(ctx.currentUser._id);
        if (userInfo.password != password) {
            ErrorUtils.throwApiError(ErrorUtils.OLD_PASSWORD_ERROR);
        }
        //新密码
        let newPassword = data.newPassword;
        newPassword = newPassword + config.auth.salt;
        newPassword.toLowerCase();
        const md51 = crypto.createHash('md5');
        md51.update(newPassword);
        newPassword = md51.digest('hex');
        userInfo.password = newPassword;
        userInfo.save();
        infoLogger.info(">>>>>>修改成功结束");
        return true;
    }

    static checkUpdateUserData(data) {
        let schema = Joi.object({
            nationality: Joi.object().keys({
                code: Joi.string().required(),
                en: Joi.string().required(),
                cn: Joi.string().required(),
            }).required(),//国籍
            name: Joi.string().min(2).max(20).required(),//姓名
            sex: Joi.number().required(),//性别
            birthday: Joi.string().required(),
            idCard: Joi.string().min(5).max(30).required(),
            status: Joi.number().required(),
            deliveryDistrict: Joi.object().required(),//区
            deliveryCity: Joi.object().required(),//市
            deliveryProvince: Joi.object().required(),//省
            deliveryAddress: Joi.string().max(40).required(),//详情地址
        });
        let result = Joi.validate(data, schema);
        return result;
    }

    /**
     *  修改用户信息
     * @param data
     * @returns {Promise<void>}
     */
    static async updateUserInfo(ctx) {
        let data = ctx.request.body;
        infoLogger.info('>>>>>>更新用户信息开始,请求参数为:', data);
        await AdminUserService.checkUpdateUserData(data);
        let baseUser = await BaseUserInfo.findOne({userId: ctx.currentUser._id}).exec();
        let baseUserInfo = lodash.pick(data, [
            'birthday', 'sex', 'nationality', 'deliveryDistrict', 'deliveryCity', 'deliveryProvince',
            'deliveryAddress'
        ]);
        baseUserInfo.sex = parseInt(data.sex);
        switch (data.sex) {
            case 0:
                break;
            case 1:
                break;
            default:
                data.sex = 2;
                break;
        }
        baseUserInfo.userId = ctx.currentUser._id;
        if (baseUser) {
            await BaseUserInfo.update({_id: baseUser._id}, baseUserInfo);
        } else {
            await BaseUserInfo.create(baseUserInfo);
        }
        let userInfo = await User.findById(ctx.currentUser._id);
        userInfo.birthday = data.birthday;
        data.status = parseInt(data.status);
        switch (data.status) {
            case 0:
                break;
            case 1:
                break;
            default:
                data.status = 2;
                break;
        }
        userInfo.status = data.status;
        userInfo.idCard = data.idCard;
        userInfo = await userInfo.save();
        await redis.setex(`${config.auth.adminLoginPrefix}${ctx.currentUser.username}`, config.auth.adminTtl, JSON.stringify(userInfo));
        infoLogger.info(">>>>>>修改成功结束");
        return true;
    }

    /**
     * 查询用户信息
     * @param ctx
     * @returns {Promise<*>}
     */
    static async findUserInfo(ctx) {
        infoLogger.info('>>>>>>用户查询接口开始');
        let data = {};
        let object = {
            sex: 0,
            birthday: '',
            nationality: {
                code: "",
                en: "",
                cn: ""
            },//国籍
            deliveryCity: {
                CityID: "",
                CityName: "",
                ProID: "",
                CitySort: ""
            },//市
            deliveryDistrict: {
                Id: "",
                DisName: "",
                CityID: "",
                DisSor: null
            },//区
            deliveryProvince: {
                ProID: "",
                ProName: "",
                ProSort: "",
                ProRemar: ""
            },//省
            deliveryAddress: '',//详情地址
            receiver: '',//收件人
            receiverTel: '',//收件人手机号
            authType: '',
        };
        let result = await BaseUserInfo.findOne({userId: ctx.currentUser._id})
            .lean()
            .exec();
        data.baseInfo = Object.assign(object, result);
        data.userInfo = ctx.currentUser;
        infoLogger.info('>>>>>>用户查询接口结束');
        return data;
    }

    /**
     * 确认申请
     * @param ctx
     * @returns {Promise<boolean>}
     */
    static async confirmApply(ctx) {
        infoLogger.info('>>>>>:确认提交开始');
        let userApply = await UserApply.findOne({userId: ctx.currentUser._id}).lean().exec();
        if (!userApply) {
            let code = lodash.random(100, 999).toString() + new Date().getTime().toString() + lodash.random(100, 999).toString();
            await UserApply.create({
                userId: ctx.currentUser._id,
                addTime: new Date(),
                status: 0,
                code: code
            });
        }
        infoLogger.info('>>>>>:确认提交结束');
        return true;
    }

    /**
     * 确认申请
     * @param ctx
     * @returns {Promise<boolean>}
     */
    static async findApplyList(ctx) {
        infoLogger.info('>>>>>:查询确认提交列表开始');
        let list = await UserApply.find({userId: ctx.currentUser._id})
            .populate({
                select: "name phone username",
                path: "userId"
            })
            .lean()
            .exec();
        infoLogger.info('>>>>>:查询确认提交列表结束');
        return list;
    }


    static async findPayDetail(ctx) {
        let userApply = await UserApply.findOne({userId: ctx.currentUser._id}).lean().exec();
        if (!userApply) {
            ErrorUtils.throwApiError(ErrorUtils.APPLY_NOT_EXISTS);
        }
        let isShow = false;
        switch (userApply.status) {
            case 0:
                isShow = true;
                let orderInfo = await Order.findOne({
                    userId: ctx.currentUser._id,
                    payStatus: 0
                }).lean().exec();
                if (orderInfo) {
                    orderInfo.isShow = isShow;
                    orderInfo.name = ctx.currentUser.name;
                    return orderInfo;
                } else {
                    let object = {};
                    object.name = ctx.currentUser.name;
                    object.orderNo = new Date().getTime();
                    object.orderName = "学历学位认证";
                    object.price = 360;
                    object.verifyType = 1;
                    object.userId = ctx.currentUser._id;
                    let re = await Order.create(object);
                    object.isShow = isShow;
                    object.name = ctx.currentUser.name;
                    infoLogger.info('>>>>>:查询支付信息开始', re);
                    return object;
                }
            case 1:
            case 2:
                isShow = false;
                let orderInfo1 = await Order.findOne({
                    userId: ctx.currentUser._id,
                    payStatus: 1
                }).lean().exec();
                orderInfo1.isShow = isShow;
                orderInfo1.name = ctx.currentUser.name;
                return orderInfo1;
            default:
                isShow = true;
                let orderInfo2 = await Order.findOne({
                    userId: ctx.currentUser._id,
                    payStatus: 0
                }).lean().exec();
                if (orderInfo2) {
                    orderInfo2.isShow = isShow;
                    orderInfo2.name = ctx.currentUser.name;
                    return orderInfo2;
                } else {
                    let object = {};
                    object.name = ctx.currentUser.name;
                    object.orderNo = new Date().getTime();
                    object.orderName = "学历学位认证";
                    object.price = 360;
                    object.payStatus = 0;
                    object.verifyType = 2;
                    object.userId = ctx.currentUser._id;
                    let re = await Order.create(object);
                    infoLogger.info('>>>>>:查询支付信息开始', re);
                    re.isShow = isShow;
                    return re;
                }
        }
    }

    static checkCreatePayOrderData(data) {
        let schema = Joi.object({
            orderNo: Joi.string().required(),
            payType: Joi.number().required(),
        });
        let result = Joi.validate(data, schema);
        return result;
    }

    static async createPayOrder(ctx) {
        let data = ctx.request.body;
        infoLogger.info('>>>>>:创建订单开始', data);
        await AdminUserService.checkCreatePayOrderData(data);
        let userApply = await UserApply.findOne({userId: ctx.currentUser._id}).lean().exec();
        if (!userApply) {
            ErrorUtils.throwApiError(ErrorUtils.APPLY_NOT_EXISTS);
        }
        if (data.payType != 1) {
            data.payType = 2;
        }
        switch (userApply.status) {
            case 0:
                let orderInfo = await Order.findOne({
                    userId: ctx.currentUser._id,
                    payStatus: 0,
                    orderNo: data.orderNo,
                }).exec();
                if (!orderInfo) {
                    ErrorUtils.throwApiError(ErrorUtils.ORDER_NOT_EXIST);
                } else {
                    let re = await Order.update({orderNo: data.orderNo},
                        {payStatus: 1, payTime: new Date(), payType: data.payType});
                    infoLogger.info('>>>>>返回结果', re);
                    await UserApply.findByIdAndUpdate(userApply._id, {status: 1});
                }
                break;
            case 1:
                ErrorUtils.throwApiError(ErrorUtils.APPLY_HAS_VERIFY);
                break;
            case 2:
                ErrorUtils.throwApiError(ErrorUtils.APPLY_SUCCESS);
                break;
            default:
                let orderInfo1 = await Order.findOne({
                    userId: ctx.currentUser._id,
                    payStatus: 0,
                    orderNo: ctx.request.body.orderNo,
                }).exec();
                if (!orderInfo1) {
                    ErrorUtils.throwApiError(ErrorUtils.ORDER_NOT_EXIST);
                } else {
                    let re = await Order.update({orderNo: data.orderNo},
                        {payStatus: 1, payTime: new Date(), payType: data.payType});
                    infoLogger.info('>>>>>返回结果', re);
                    await UserApply.findByIdAndUpdate(userApply._id, {status: 1});
                }
                break;
        }
    }

    /**
     * 确认申请
     * @param ctx
     * @returns {Promise<boolean>}
     */
    static async findPayList(ctx) {
        infoLogger.info('>>>>>:查询支付列表开始');
        let list = await Order.find({userId: ctx.currentUser._id})
            .lean()
            .exec();
        for(let i=0;i<list.length;i++){
            let result = await BaseUserInfo.findOne({userId: ctx.currentUser._id})
                .lean()
                .exec();
            if(result){
                list[i].authType=result.authType;
            }else{
                list[i].authType=0;
            }
        }
        infoLogger.info('>>>>>:查询支付列表结束');
        return list;
    }
    /**
     * 确认申请
     * @param ctx
     * @returns {Promise<boolean>}
     */
    static async findLiuyanList(ctx) {
        infoLogger.info('>>>>>:查询留言列表开始');
        let list = await Liuyan.find({userId: ctx.currentUser._id})
            .lean()
            .exec();
        infoLogger.info('>>>>>:查询留言列表结束');
        return list;
    }
}

module.exports = AdminUserService;
